package com.xcc.core.netty;


import java.math.BigInteger;

import javax.net.ssl.SSLEngine;

import com.xcc.core.config.PropertiesUtil;
import com.xcc.core.netty.client.ClientLengthHandler;
import com.xcc.core.netty.client.RealLengthClientHandler;
import com.xcc.core.netty.coder.FixedLengthFrameDecoder;
import com.xcc.core.netty.coder.FixedLengthFrameEncoder;
import com.xcc.core.netty.manager.ManagerChannel;
import com.xcc.core.netty.model.LengthModel;
import com.xcc.core.netty.ssl.MyClientSslContextFactory;
import com.xcc.core.netty.ssl.MyServerSslContextFactory;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.ssl.SslHandler;

public class NettyLengthClient {


    private final String host;
    private final int port;
    private Channel channel;

    //连接服务端的端口号地址和端口号
    public NettyLengthClient(String host, int port) {
        this.host = host;
        this.port = port;
    }

    public void start() throws Exception {
        EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap b = new Bootstrap();
        b.group(group).channel(NioSocketChannel.class)  // 使用NioSocketChannel来作为连接用的channel类
       .option(ChannelOption.TCP_NODELAY, true)
        .handler(new ChannelInitializer<SocketChannel>() { // 绑定连接初始化器
            @Override
            public void initChannel(SocketChannel ch) throws Exception {
                ChannelPipeline pipeline = ch.pipeline();
                SSLEngine ssl=   MyClientSslContextFactory.getsslClient();
                pipeline.addLast(new SslHandler(ssl));
                pipeline.addLast(new FixedLengthFrameDecoder()) ;  
                pipeline.addLast(new FixedLengthFrameEncoder()) ;  
                pipeline.addLast(new ClientLengthHandler()); //客户端处理类
            }
        });
        //发起异步连接请求，绑定连接端口和host信息
        final ChannelFuture future = b.connect(host, port).sync();

        future.addListener(new ChannelFutureListener() {

            @Override
            public void operationComplete(ChannelFuture arg0) throws Exception {
                if (future.isSuccess()) {
                    System.out.println("内部服务连接成功");
                } else {
                    System.out.println("内部服务连接失败");
                    //重连
                }
            }
        });
        this.channel = future.channel();
    }

    public Channel getChannel() {
        return channel;
    }
    
    
    public static void startProClient(int id) {
        
        EventLoopGroup group = new NioEventLoopGroup();
        Bootstrap b = new Bootstrap();

        b.group(group).channel(NioSocketChannel.class)  // 使用NioSocketChannel来作为连接用的channel类
       .option(ChannelOption.TCP_NODELAY, true)
        .handler(new ChannelInitializer<SocketChannel>() { // 绑定连接初始化器
            @Override
            public void initChannel(SocketChannel ch) throws Exception {
                System.out.println("正在连接中...");
                ChannelPipeline pipeline = ch.pipeline();
                pipeline.addLast(new RealLengthClientHandler()); //客户端处理类
            }
        });

        ChannelFuture future;
        try {
            future = b.connect(PropertiesUtil.getValue("proxy.ip"), PropertiesUtil.getIntValue("proxy.port")).sync();
            future.addListener(new ChannelFutureListener() {

                @Override
                public void operationComplete(ChannelFuture arg0) throws Exception {
                    if (future.isSuccess()) {
                        int id1=  new BigInteger(future.channel().id().asShortText(), 16).intValue();
                        System.out.println("发送给真服务id"+id1);
                        ManagerChannel.channelMapper.put(id1+"", id+"");
                        Channel  ch = ManagerChannel.getServerChannel("3389");
                        LengthModel mLengthModel=new LengthModel();
                        byte[] bs=("connected&"+id1).getBytes();
                        mLengthModel.setId(id);
                        mLengthModel.setBs(bs);
                        mLengthModel.setLength(bs.length);
                        ch.writeAndFlush(mLengthModel);
                    } else {
                        
                        System.out.println("连接服务器失败");
                        //重连
                        startProClient(id);
                    }
                }
            });

        } catch (InterruptedException e) {
            e.printStackTrace();
        }finally {
            
        }

    }
    
    
    
    
    public static void main(String[] args) throws Exception {
        new NettyLengthClient(PropertiesUtil.getValue("server.ip"),PropertiesUtil.getIntValue("server.port")).start();
     //   startProClient();
    }
}
